【コードでインフラ定義】CDKという異次元体験をさくっとやるのに便利なAWS公式Workshopの紹介
「俺もそろそろ乗らなくては、この、ビッグウェーブに!!」
皆さん、CDK触っていますか?DevelopersIOにも、CDK | 特集カテゴリー で、既に20以上のブログがあがっていたり、その人気はうなぎのぼりです。
CDKとは一口で言えば「コードでインフラを定義する」ものです。「いやぁ、これ楽。素晴らしい」という声を同僚からよく聞くので、自分も早速試してみようとしたところ、CDK Workshopなるものを発見し、手を動かして学ぶには凄くわかりやすく良い教材だったので、その内容を紹介します。
- CDK実行するための環境定義
- LambdaとAPI Gatewayを利用した簡単なサービスの公開
- モジュールの作り方
- クラス構造の解説
- デバッグ方法
- モジュールの利用方法
- 関連リソースの一括削除
これらをおよそ2時間ほどで体験できるので、まずはサクッと手を動かして、この新鮮な感覚をぜひ皆さんに味わってもらいたいなと思います。
(祭) ∧ ∧ Y ( ゚Д゚) Φ[_ソ__y_l〉 CDKマツリダワッショイ |_|_| し'´J
「CDK」とは
What Is the AWS CDK? - AWS Cloud Development Kit (AWS CDK)
「コードでインフラを定義する」ものです。従来から提供されているCloudFormationは、基本JSONやYAMLといった構造化ファイルでリソースを定義していたのですが、CDKでは、いわゆるひとつのアプリケーションコード(TypeScript、JavaScript、Python、Java、C#/.NET)を利用できるのが大きな違いと言えます。
「CDK Workshop」とは
こちらからアクセスできます。
AWS CDK Intro Workshop :: AWS Cloud Development Kit (AWS CDK) Workshop
AWSのWorkshopは他にもありますが、基本的には「手を動かしながらその分野を学ぶための材料がまとめられたWebサイト」という認識で良いです。
CDKは、JavaScript, TypeScript, Python, Java, .NETに対応していますが、Workshopで対応しているのはTypeScriptとPythonのみです。
このWorkshopを終了すると、以下を達成できるとのこと。CDKについての基礎は学べそうです。
- Create new CDK applications.
- Define your app’s infrastructure using the AWS Construct Library
- Deploy your CDK apps to your AWS account
- Define your own reusable constructs
- Consume constructs published by other people
今回、ハマコーは独断と偏見でTypeScriptを使ってみます。
Prerequisites(環境セットアップ、前提の確認)
最初に環境セットアップとして、以下を順に実施していきます。
- AWS CLI
- AWS Account and User
- Node.js
- IDE for your programming language
- AWS CDK Toolkit
- Python
ただ、実施内容はほぼほぼこちらのドキュメントと同じなので、どちらかを参照しながらできれば良いと思います。
Workshopでは、IAMユーザーの作成から全て丁寧に教えてくれるので、AWS自体の経験が少ない方は、WorkShopを参照されることをオススメします。
IDEの設定
ここは、Workshopならではのところ。以下のIDEが推奨されていて、一番オススメはVSCodeとのことです。
- VSCode (recommended)
- AWS Cloud9
- Atom with the atom-typescript plugin
- vim with tsuquyomi
- WebStorm
- Emacs with the tide mode
- PyCharm
自分の普段利用エディタはVSCodeなので、VSCodeにTypeScriptの環境を作っておきましょう。自分は事前に、VSCodeオフィシャルのこちらのドキュメントみて、一通り実行してみました。あわせて、TypeScriptの初歩の初歩の感触をつかむのにも有用です。
CDKのインストール
本丸、CDKのセットアップです。下のコマンドを叩くだけ。簡単。
$ npm install -g aws-cdk
インストールが完了したら、バージョンを確認します。
$ cdk --version 1.8.0 (build 5244f97)
TypeScriptによるCDK Workshopの体験
いよいよ、Workshopを進めながらCDK体験していきます。Workshopは以下の章立てで構成されています。
- New Project
- Hello, CDK!
- Writing constructs
- Using construct libraries
- Clean up
以降、各章について、内容を紹介していきます。
New Project(プロジェクトの新規作成)
New Project :: AWS Cloud Development Kit (AWS CDK) Workshop
基礎の学習
一番最初にCDKプロジェクトを作成しつつ、CDKの基本をおさらいしていきます。
npm run watch
を使った、.ts
(typescript)から自動で.js
(JavaScript)を生成する設定が紹介されたのち、CDKプロジェクトの各ファイルの役割の説明があります。ここは必見です。
Project structure :: AWS Cloud Development Kit (AWS CDK) Workshop
といっても、最初はあまりピンとこない部分が多いと思うので、さらっと説明を読んで一覧しつつ、メインファイルのエントリポイントと、アプリケーション用ファイルが何なのかを理解します。
- エントリーポイント
bin/cdk-worksho.ts
- 基本的には変更する必要なし
- アプリケーションのメインファイル
lib/cdk-workshop-stack.ts
- アプリケーションの構築で利用するファイルは主にこちら
import sns = require('@aws-cdk/aws-sns'); import subs = require('@aws-cdk/aws-sns-subscriptions'); import sqs = require('@aws-cdk/aws-sqs'); import cdk = require('@aws-cdk/core'); export class CdkWorkshopStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); const queue = new sqs.Queue(this, 'CdkWorkshopQueue', { visibilityTimeout: cdk.Duration.seconds(300) }); const topic = new sns.Topic(this, 'CdkWorkshopTopic'); topic.addSubscription(new subs.SqsSubscription(queue)); } }
このコードだけで、以下の4つのリソースが作成されます。これ凄いな。
- AWS::SQS::Queue
- AWS::SNS::Topic
- AWS::SNS::Subscription
- AWS::SQS::QueuePolicy
cdk synthによるCloudFormationテンプレートの作成
CDKプロジェクト内、以下のコマンドでCDKよりCloudFormationのテンプレートが標準出力されます。
$ cdk synth
CDKは裏側では、AWSのAPIを直接叩いているわけではなく、一度CloudFormationのテンプレートとスタックが作成されて、そこからAWSの各種リソースが作成される仕組みというのがここから実感できます。
リソースのデプロイ
いよいよリソースをAWS環境に作ります。
最初に、CDK toolkitのオペレーションに必要なS3バケットを作成します。
$ cdk bootstrap
そうすると、CloudFormationが動いて専用のS3バケットが作成されます。関係ないけど、CDKのコマンドは結果が非常にカラフルで見た目わかりやすくて良い.
Webコンソールを確認すると、しっかりCDKToolkit
というスタックとS3バケットが生成されていることがわかります。
この前処理が終わったら、いよいよリソース作成していきます。
$ cdk deploy
このコマンドを実行すると、途中で「ほんとにやっていいの?大丈夫?」的な確認を求められます。ここらへん、terraformと似てますね。
y
を押すと無事、リソースが作成されます。
Do you wish to deploy these changes (y/n)? y CdkWorkshopStack: deploying... CdkWorkshopStack: creating CloudFormation changeset... 0/6 | 06:28:12 | CREATE_IN_PROGRESS | AWS::SNS::Topic | CdkWorkshopTopic (CdkWorkshopTopicD368A42F) 0/6 | 06:28:12 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata 0/6 | 06:28:13 | CREATE_IN_PROGRESS | AWS::SQS::Queue | CdkWorkshopQueue (CdkWorkshopQueue50D9D426) 0/6 | 06:28:13 | CREATE_IN_PROGRESS | AWS::SNS::Topic | CdkWorkshopTopic (CdkWorkshopTopicD368A42F) Resource creation Initiated 0/6 | 06:28:13 | CREATE_IN_PROGRESS | AWS::SQS::Queue | CdkWorkshopQueue (CdkWorkshopQueue50D9D426) Resource creation Initiated 1/6 | 06:28:14 | CREATE_COMPLETE | AWS::SQS::Queue | CdkWorkshopQueue (CdkWorkshopQueue50D9D426) 1/6 | 06:28:14 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata Resource creation Initiated 2/6 | 06:28:14 | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata 3/6 | 06:28:23 | CREATE_COMPLETE | AWS::SNS::Topic | CdkWorkshopTopic (CdkWorkshopTopicD368A42F) 3/6 | 06:28:25 | CREATE_IN_PROGRESS | AWS::SNS::Subscription | CdkWorkshopQueue/CdkWorkshopStackCdkWorkshopTopicD7BE9643 (CdkWorkshopQueueCdkWorkshopStackCdkWorkshopTopicD7BE96438B5AD106) 3/6 | 06:28:26 | CREATE_IN_PROGRESS | AWS::SQS::QueuePolicy | CdkWorkshopQueue/Policy (CdkWorkshopQueuePolicyAF2494A5) 3/6 | 06:28:26 | CREATE_IN_PROGRESS | AWS::SQS::QueuePolicy | CdkWorkshopQueue/Policy (CdkWorkshopQueuePolicyAF2494A5) Resource creation Initiated 3/6 | 06:28:26 | CREATE_IN_PROGRESS | AWS::SNS::Subscription | CdkWorkshopQueue/CdkWorkshopStackCdkWorkshopTopicD7BE9643 (CdkWorkshopQueueCdkWorkshopStackCdkWorkshopTopicD7BE96438B5AD106) Resource creation Initiated 4/6 | 06:28:26 | CREATE_COMPLETE | AWS::SQS::QueuePolicy | CdkWorkshopQueue/Policy (CdkWorkshopQueuePolicyAF2494A5) 5/6 | 06:28:26 | CREATE_COMPLETE | AWS::SNS::Subscription | CdkWorkshopQueue/CdkWorkshopStackCdkWorkshopTopicD7BE9643 (CdkWorkshopQueueCdkWorkshopStackCdkWorkshopTopicD7BE96438B5AD106) 6/6 | 06:28:28 | CREATE_COMPLETE | AWS::CloudFormation::Stack | CdkWorkshopStack ✅ CdkWorkshopStack Stack ARN: arn:aws:cloudformation:ap-northeast-1:123456789012:stack/CdkWorkshopStack/303a18f0-df12-11e9-9e06-0e8a9cd56576
WebコンソールのCloudFormationからも、作成されたリソースを確認できます。
ここまでで、CDKの基本的な動作の確認は完了です。
Hello, CDK!(CDKを始める)
Hello, CDK! :: AWS Cloud Development Kit (AWS CDK) Workshop
前章で基礎の基礎を学んだあと、ここでは、より実践的なアプリケーションを作成していきます。Lambda functionとAPI Gatewayのエンドポイントを作成し、アクセスすると、ハートウォーミングなメッセージが表示されるとのこと。どんなんやそれ。
サンプルリソースの削除
もともとのサンプルには、SNSとSQSのリソースを入れていたけれど、これは特に使う予定がない(!)ということで、最初にこれらリソース削除します。対象ファイルから、関連リソースのコードを削除したのち、以下のコマンドで、クライアントのStackをリモートにデプロイした時に実施されるリソースの変更を事前に確認できます。CloudFormationにおけるChangeset、TerraformにおけるPlanみたいなものすね。
$ cdk diff
そうすると、こんなグラフィカルな感じで、変更差分を出力してくれます。dstroy
される部分が、赤文字で表示されるのは非常にわかりやすいです。正直、CloudFormationのChangesetより300万倍わかりやすいかと。
この結果が問題なければ、再度cdk deploy
することで、上で表示されたリソースが無事削除されます。
LambdaをCDKで書いてみる
いよいよ、実践編。LambdaをCDKで構築してみます。Lambdaで利用するコードは、CDKプロジェクトの中にCDKのコードとは別で格納します。
exports.handler = async function(event) { console.log('request:', JSON.stringify(event, undefined, 2)); return { statusCode: 200, headers: { 'Content-Type': 'text/plain' }, body: `Hello, CDK! You've hit ${event.path}\n` }; };
AWS Lambda construct libraryのインストール
CDKでは、AWSの各リソースに対応したモジュールをAWS Construct Libraryとして提供しています。インストール方法は簡単。以下のようにnpm install
を利用します。
$ npm install @aws-cdk/aws-lambda
Typescriptの威力をもろに感じるのがここらへんですね。コード中インポートしたモジュールから利用するクラスの自動補完が効きまくるので非常にコーディングが楽です。こんな感じ。
是非、サンプルコードについては、コピペするのではなく、実際にタイピングしてみて、その補完の効き具合に感動してみるのをオススメします。
その後は、cdk diff
からのcdk deploy
で、いつものLambdaが作成されることを確認します。
API Gatewayの構築
似たような手順で、API Gatewayも構築していきます。API GatewayのモジュールをLambdaと同様の手順でインストールした後、cdk-workshop-stack.ts
を編集、cdk diff
からcdk deploy
により、API Gatewayが作成されます。
作成されたAPI Gatewayのエンドポイントにcurlを投げてみて、無事以下のレスポンスが返ってくればOKです。
$ curl https://ozn9heg0s6.execute-api.ap-northeast-1.amazonaws.com/prod/ Hello, CDK! You've hit /
Writing Constructs(モジュールの作成)
Writing constructs :: AWS Cloud Development Kit (AWS CDK) Workshop
ここでは、簡単なカウンターアプリを作成しながら、自作モジュールの作成方法や権限周辺のトラブルシュートを習得します。
ヒットカウンターモジュールの作成、Lambdaコードの作成
内容としては、最初にヒットカウンターのモジュールを作っていくんですが、このWorkshopの良い点は、各ソースコードについて、それぞれの構造のポイントがシンプルに記載されている点。
このコードに対して。
import cdk = require('@aws-cdk/core'); import lambda = require('@aws-cdk/aws-lambda'); export interface HitCounterProps { /** the function for which we want to count url hits **/ downstream: lambda.IFunction; } export class HitCounter extends cdk.Construct { constructor(scope: cdk.Construct, id: string, props: HitCounterProps) { super(scope, id); // TODO } }
こんな解説が都度ついてきます。
このあたりの解説ですが、そもそものTypeScriptそのものの最低限の知識が無いとよくわからないと思うので、事前に言語そのものの知識を習得しておくことをオススメします。このコードだとTypeScriptにおけるInterfaceの使われ方をしっておいたほうがピンとくると思います。
自分は、こちらの記事(Typescriptのinterfaceの使い方 - Qiita)を参考にしました。
CloudWatch Logsによるデバッグ
実際にコードして動かしてみるのですが、エラーになります。このWorkshopでは意図的にエラーとなるコードが仕組まれていて、「わお!エラーがでましたね。でも落ち着いてデバッグしていきましょ〜」的なのりで、CloudWatch Logsの画面を確認します。
このあたりは、Lambdaのデバッグでよくやる内容なので、慣れている人はわかりやすいかと思います。主に、権限が足りていないところをデバッグしてコードを修正していきます。
最後の動作確認
これらコードの修正をして、最終的にGETリクエストを投げると、DynamoDBのパス付きでリクエストされた回数がカウントされるアプリケーションが構築されます。あとは、好きにコードをカスタマイズしながら、理解を深めてみれば良いんじゃないでしょうか。
Using construct libraries(ライブラリーの利用)
Using construct libraries :: AWS Cloud Development Kit (AWS CDK) Workshop
ここでは、npmでインストールできるライブラリーを利用して、さらにアプリケーションを拡張していきます。利用するライブラリーはこちら。
引数で与えたDynamoDBのテーブル内容を表示するモジュールです。利用方法は簡単。npm install
でモジュールをインストールしたのち、cdk-workshop-stack.ts
に、TableViewer
という名前でモジュールを追加。クラス生成するときに必要なDynamoDBのテーブル名をhitcounter.ts
でパブリック指定した変数から取得するようにコードを修正します。
改めて、cdk deploy
することで、簡単に画面を追加することができました。API GatewayのエンドポイントにGETリクエストを投げたときのパス別に集計されたDynamoDBテーブルの内容が、一覧できます。
Clean Up(作成したリソースの削除)
ここまでもろもろ作成したリソースの削除もIaCならではの簡単一発。cdk destroy
だけ。
$ cdk destroy Are you sure you want to delete: CdkWorkshopStack (y/n)? y
CDKという異次元体験を2時間で体験できる最良のWorkshop
自分これで初めてCDK触ってたんですが、CloudFormationで細かくYAMLとリソースのプロパティを書いていたときとは全く異なるレイヤーで、インフラやサービスそのものを定義できるのには驚きました。デフォルトでCDK側で設定されるプロパティが多いためか、APIレベルでの指定必須項目をほぼほぼ省略できるため、コード量が非常に少なくなります。
CDK書いてて思うのは、今までなにかサービスをデプロイしようとしたときに、CFnとかだとあくまで個別要素の「インフラの組み合わせ」という観点でyamlを書いていたのが、もう少しレイヤーがあがって「サービスで実現したいこと」という観点で書ける部分が増えたのが素敵な気がする。
— 濱田孝治(ハマコー) (@hamako9999) September 25, 2019
自分はブログを書きながら試してみましたが、このWorkshop、内容は非常にコンパクトに纏まっていて、CDKが持つその威力と基本的な考え方は十分このWorkshopで体験することができます。
特にトラブルがなければ2時間程度で終了するボリュームなので、「最近、めっちゃアツいと噂のCDK、体験してみたいなぁ」という人で、TypeScriptにある程度馴染みがあるかたは、まずはこのWorkshopを実施してみることをオススメします。
また、同じWorkshop内にはPython版もほぼ同じ内容で存在するので、文法的にPythonが馴染みがあるかたは、ぜひこちらも試してみていただければと思います。
それでは、今日はこのへんで。濱田(@hamako9999)でした。
(おまけ)他のWorkshopもあり、初学にオススメ
AWSからは、他にも様々なWorkshopが提供されています。弊社園部治が、下記記事にまとめているので、是非こちらもご参照ください。